package com.tools.handler.analysis;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.tools.common.result.Result;
import com.tools.handler.StepHandler;
import com.tools.pojo.analysis.dto.MedicalAnalysisResult;
import com.tools.pojo.analysis.dto.PatientAnalysisResult;
import com.tools.pojo.analysis.dto.RuleStatistics;
import com.tools.pojo.test.AnalysisResult;
import com.tools.pojo.workflow.bo.StepContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DetailedReportStepHandler implements StepHandler {

    private static final String STEP_CODE = "DETAILED_REPORT";

    @Override
    public String getStepCode() {
        return STEP_CODE;
    }
    @Override
    public Result<?> execute(StepContext context) {
        try {
            log.info("开始执行详细分析报告步骤，流程实例ID: {}", context.getFlowInstanceId());

            Map<String, Object> contextData = context.getContextData();
            Object data = contextData.get("analysisResult");
            AnalysisResult analysisResult;
            if (data instanceof Map) {
                ObjectMapper objectMapper = new ObjectMapper();
                analysisResult = objectMapper.convertValue(data, AnalysisResult.class);
            } else if (data instanceof AnalysisResult) {
                analysisResult = (AnalysisResult) data;
            } else {
                throw new IllegalStateException("未知的数据类型");
            }



            if (analysisResult == null) {
                return Result.fail("未找到分析结果");
            }

            // 检查是否为多患者分析结果
            if (analysisResult instanceof MedicalAnalysisResult medicalResult) {
                generateMultiPatientReport(medicalResult, context);
            } else {
                generateSinglePatientReport(analysisResult, context);
            }

            // 标记当前报告类型
            context.putContextData("reportType", "DETAILED");
            context.putContextData("reportGenerated", true);

            log.info("详细分析报告生成完成");
            return Result.success("详细分析报告生成完成");

        } catch (Exception e) {
            log.error("详细分析报告步骤执行失败", e);
            return Result.fail("详细分析报告生成失败: " + e.getMessage());
        }
    }

    /**
     * 生成多患者报告
     */
    private void generateMultiPatientReport(MedicalAnalysisResult result, StepContext context) {
        System.out.println("\n" + "=".repeat(120));
        System.out.println("                         多患者医疗数据分析报告");
        System.out.println("=".repeat(120));

        // 执行摘要
        System.out.println("执行摘要:");
        System.out.println("-".repeat(120));
        System.out.printf("分析时间: %d ms\n", result.getProcessingTime());
        System.out.printf("患者总数: %d 人\n", result.getTotalPatients());
        System.out.printf("匹配患者: %d 人 (%.2f%%)\n",
                result.getPatientsWithMatches(),
                (double) result.getPatientsWithMatches() / result.getTotalPatients() * 100);
        System.out.printf("规则总数: %d 条\n", result.getPatientResults().get(0).getTotalRules());
        System.out.printf("平均匹配规则: %.2f 条/患者\n", result.getAverageMatchedRules());

        // 患者分析详情
        System.out.println("\n患者分析详情:");
        System.out.println("-".repeat(120));
        System.out.printf("%-4s %-20s %-15s %-10s %-15s %-8s %s\n",
                "序号", "患者姓名", "患者ID", "性别", "主要诊断", "匹配规则", "状态");
        System.out.println("-".repeat(120));

        for (PatientAnalysisResult patientResult : result.getPatientResults()) {
            String status = patientResult.getMatchedRules() > 0 ? "✓" : "✗";
            System.out.printf("%-4d %-20s %-15s %-10s %-15s %-8s %s\n",
                    patientResult.getRecordIndex() + 1,
                    truncate(patientResult.getPatientName(), 18),
                    truncate(patientResult.getPatientId(), 13),
                    getGenderText(patientResult.getGender()),
                    truncate(patientResult.getMainDiagnosis(), 13),
                    patientResult.getMatchedRules() + "/" + patientResult.getTotalRules(),
                    status);
        }

        // 规则匹配统计
        System.out.println("\n规则匹配统计:");
        System.out.println("-".repeat(120));
        System.out.printf("%-4s %-25s %-8s %-8s %s\n",
                "ID", "规则名称", "匹配患者", "总患者", "匹配率");
        System.out.println("-".repeat(120));

        for (RuleStatistics ruleStat : result.getRuleStatistics()) {
            System.out.printf("%-4d %-25s %-8d %-8d %.2f%%\n",
                    ruleStat.getRuleId(),
                    truncate(ruleStat.getRuleName(), 23),
                    ruleStat.getMatchedPatients(),
                    ruleStat.getTotalPatients(),
                    ruleStat.getMatchRate());
        }

        // 临床洞察
        System.out.println("\n临床洞察:");
        System.out.println("-".repeat(120));
        generateMedicalInsights(result, context);

        System.out.println("=".repeat(120));

        // 记录到日志
        log.info("多患者详细报告生成: {}/{}患者匹配, 平均{}规则/患者",
                result.getPatientsWithMatches(), result.getTotalPatients(),
                String.format("%.2f", result.getAverageMatchedRules()));
    }

    /**
     * 生成单患者报告（兼容原有逻辑）
     */
    private void generateSinglePatientReport(AnalysisResult result, StepContext context) {
        // 原有的单患者报告生成逻辑
        // 这里省略具体实现
    }

    /**
     * 生成医疗洞察
     */
    private void generateMedicalInsights(MedicalAnalysisResult result, StepContext context) {
        // 分析患者群体特征
        long hypertensionCount = result.getPatientResults().stream()
                .filter(pr -> pr.getMainDiagnosis() != null && pr.getMainDiagnosis().contains("高血压"))
                .count();

        long femaleCount = result.getPatientResults().stream()
                .filter(pr -> "2".equals(pr.getGender()))
                .count();

        double avgAge = result.getPatientResults().stream()
                .filter(pr -> pr.getAge() != null && pr.getAge() > 0)
                .mapToInt(PatientAnalysisResult::getAge)
                .average()
                .orElse(0.0);

        System.out.printf("👥 患者群体: %d名患者，平均年龄%.1f岁，女性占比%.1f%%\n",
                result.getTotalPatients(), avgAge,
                (double) femaleCount / result.getTotalPatients() * 100);

        if (hypertensionCount > 0) {
            System.out.printf("❤️  高血压患者: %d人 (%.1f%%)\n",
                    hypertensionCount,
                    (double) hypertensionCount / result.getTotalPatients() * 100);
        }

        // 药物使用分析
        Map<String, Long> medicationFrequency = result.getPatientResults().stream()
                .filter(pr -> pr.getMedications() != null)
                .flatMap(pr -> pr.getMedications().stream())
                .collect(Collectors.groupingBy(med -> med, Collectors.counting()));

        if (!medicationFrequency.isEmpty()) {
            System.out.println("💊 常用药物:");
            medicationFrequency.entrySet().stream()
                    .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
                    .limit(5)
                    .forEach(entry -> System.out.printf("   %s: %d名患者使用\n",
                            truncate(entry.getKey(), 20), entry.getValue()));
        }

        // 匹配规则分析
        if (result.getAverageMatchedRules() > result.getPatientResults().get(0).getTotalRules() * 0.7) {
            System.out.println("💡 数据质量优秀，大部分患者符合多条业务规则");
        } else if (result.getAverageMatchedRules() > result.getPatientResults().get(0).getTotalRules() * 0.3) {
            System.out.println("💡 数据质量良好，建议关注未匹配规则的病例");
        } else {
            System.out.println("⚠️  数据匹配率较低，建议检查数据质量或调整规则");
        }
    }

    private String getGenderText(String genderCode) {
        if ("1".equals(genderCode)) return "男";
        if ("2".equals(genderCode)) return "女";
        return "未知";
    }

    private String truncate(String str, int length) {
        if (str == null) return "";
        return str.length() > length ? str.substring(0, length - 3) + "..." : str;
    }

}
